In [5]:
# We make a sequence consisting of a bsic element with:
# a wait time, a ramp up, a sine, a ramp down, and more wait time
# And then we vary the sine frequency
%matplotlib notebook
import broadbean as bb
from broadbean.plotting import plotter
import numpy as np
sine = bb.PulseAtoms.sine
ramp = bb.PulseAtoms.ramp
##########################
# settings
SR = 25e9
t1 = 10e-9 # first wait time (s)
ramp_time = 5e-9 # the ramp time (s)
t_sine = 25e-9 # the sine time (s)
high_level = 0.1 # the high level (V)
sine_amp = 0.05 # the sine amplitude (V)
t2 = 150e-9 # the second wait time (s)
f0 = 1e9 # the base frequency of the sine (Hz)
baseshape = bb.BluePrint()
baseshape.insertSegment(0, ramp, (0, 0), dur=t1)
baseshape.insertSegment(1, ramp, (0, high_level), dur=ramp_time)
baseshape.insertSegment(2, sine, (f0, sine_amp, high_level, 0), dur=t_sine, name='drive')
baseshape.insertSegment(3, ramp, (high_level, 0), dur=ramp_time)
baseshape.insertSegment(4, ramp, (0, 0), dur=t2, name='wait')
baseshape.setSegmentMarker('wait', (0, t_sine), 1)
baseshape.setSegmentMarker('drive', (0, t_sine), 2)
baseshape.setSR(SR)
In [6]:
# Check that it looks the way we expect
plotter(baseshape)
In [7]:
# Make it into a sequence
baseelem = bb.Element()
baseelem.addBluePrint(1, baseshape)
# Add elements and vary the sine freq.
sine_freqs = np.linspace(1e9, 2e9, 5)
seq = bb.Sequence()
seq.setSR(SR)
# We set each element of the sequence to wait for
# a trigger from trigger input 'A'
for index, freq in enumerate(sine_freqs):
elem = baseelem.copy()
elem.changeArg(1, 'drive', 'freq', freq)
seq.addElement(index+1, elem)
seq.setSequencingTriggerWait(index+1, 1) # 1: trigA, 2: trigB, 3: EXT
# and set the last element to point back to the first one
seq.setSequencingGoto(index+1, 1)
seq.name = 'tutorial_sequence' # the sequence name will be needed later
In [4]:
# import and initialise the driver and ensure that the sample
# rate and channel voltage is correct
from qcodes.instrument_drivers.tektronix.AWG70002A import AWG70002A
awg = AWG70002A('awg', 'TCPIP0::172.20.2.243::inst0::INSTR')
In [5]:
awg.sample_rate(SR)
awg.ch1.awg_amplitude(0.5) # this is the peak-to-peak amplitude of the channel
# Now we must update the Sequence object with this information
seq.setChannelAmplitude(1, awg.ch1.awg_amplitude())
In [6]:
# If the sequence has been built correctly, it's a one-liner
seqx_input = seq.outputForSEQXFile()
In [7]:
# compile a binary .seqx file
seqx_output = awg.makeSEQXFile(*seqx_input)
In [8]:
# transfer it to the awg harddrive
awg.sendSEQXFile(seqx_output, 'tutorial.seqx')
In [9]:
# load it into awg active memory
awg.loadSEQXFile('tutorial.seqx')
In [10]:
# assign tracks from the sequence to the awg sequencer
awg.ch1.setSequenceTrack('tutorial_sequence', 1)
# NB: Each channel has an assigned resolution, either 8, 9, or 10.
# 8 means 8 bits for the waveform, 2 bits for the markers (i.e. 2 markers)
# 9 means 9 bits for the waveform, 1 bit for the markers (i.e. 1 marker)
# 10 means 10 bit for the waveform, no markers
#
# Since we want to have two markers, we make sure that the resolution is 8
awg.ch1.resolution(8)
In [11]:
awg.ch1.state(1)
awg.play()
In [12]:
# force trigger the instrument to play the next part of the sequence
awg.force_triggerA()
In [13]:
# eventually shut down and turn off
awg.stop()
awg.ch1.state(0)
awg.close()